import { mapState, mapActions } from 'vuex'
import { makeUUID } from '@/utils'
/**
 * 属性面板实现的思路
 * 1、借鉴观察者模式的思想,图元称为subject(观察者目标), 界面面板称为observer(观察者)
 * 2、props.vue组件同时集成了3个mixins: selection.js、observe.js、property.js
 *    流程: 用户鼠标选择图元 --> 触发ocx的SelectModified事件
 *          --> 触发action: editor/diagram/updateSelection   (store/modules/editor/diagram.js)
 *          --> 监控selectionStamp                       (selection.js)
 *          --> 调用onSelectionChange()                  (props.vue)
 *          --> 触发action: editor/diagram/updateSubjects    (store/modules/editor/diagram.js)
 *          --> 监控observeState                         (observe.js)
 *          --> 调用onSubjectChange()                    (props.vue)
 *          --> 触发action: editor/diagram/getProperties     (store/modules/editor/diagram.js)
 *          --> 调用onGetProperties                      (property.js)
 *          --> 更新界面
 * 3、观察者目标不一定非得通过selection得到。
 *    比如用户通过命令修改了一个图元的参数, 可以通过触发action: editor/diagram/updateSubjects来通知界面更新
 */
export default {
  data() {
    return {
      // 要获取属性的图元id
      propertyEntities: null,
      // 属性操作签名
      propertySignature: ''
    }
  },
  computed: {
    ...mapState('editor/diagram', {
      // 箭头函数可使代码更简练
      // count: state => state.count,
      // 传字符串参数 'count' 等同于 'state => state.count'
      // countAlias: 'count',
      // 为了能使用 'this'获取局部状态，必须使用常规函数
      // countPlusLocalState (state) {
      //   return state.count + this.localCount
      // },
      _propertyState(state) {
        // console.log('propertyState:', state.propertyState[this.propertySignature])
        if (this.propertySignature === '') {
          return false
        } else if (state.propertyState[this.propertySignature] === undefined) {
          return false
        } else {
          return state.propertyState[this.propertySignature]
        }
      },
      // _propertyEntities(state) {
      //   if (this.propertySignature === '') {
      //     return 0
      //   } else if (state.propertyEntities[this.propertySignature] === undefined) {
      //     return 0
      //   } else {
      //     return state.propertyEntities[this.propertySignature]
      //   }
      // },
      _propertyResult(state) {
        if (this.propertySignature === '') {
          return null
        } else if (state.propertyResult[this.propertySignature] === undefined) {
          return null
        } else {
          return state.propertyResult[this.propertySignature]
        }
      }
    })
  },
  watch: {
    _propertyState: {
      handler(newVal, oldVal) {
        console.log('watch --> _propertyState:', oldVal, ' --> ', newVal)
        // 2个前提条件:
        // 1) id
        // 2) 命令状态变化(oldVal=true -->  newVal=false)
        if (this.propertyEntities && oldVal && !newVal) {
          // 根据结果更新组件数据
          this.onGetProperties(this.propertyEntities, this._propertyResult)
          // 结束属性数据操作
          this._propsUnInit()
        }
      },
      // https://www.cnblogs.com/shiningly/p/9471067.html
      // 第一次绑定的时候，不会执行监听函数，只有值发生改变才会执行。
      // 如果我们需要在最初绑定值的时候也执行函数，则就需要用到immediate属性
      immediate: false
    }
  },
  methods: {
    ...mapActions('editor/diagram', {
      // _beginGetProperties: 'beginGetProperties',
      _endGetProperties: 'endGetProperties',
      // _getProperties: 'getProperties',
      // _setProperties: 'setProperties'
      _getProperties: 'getProperties2',
      _setProperties: 'setProperties2'
    }),
    _propsInit(parts) {
      this.propertyEntities = parts
      // 创建本地签名
      this.propertySignature = makeUUID()
      // 初始化属性操作状态
      // this._beginGetProperties({ part, signature: this.propertySignature })
    },
    _propsUnInit() {
      // 结束属性数据操作
      this._endGetProperties(this.propertySignature)
      // this.propertyEntities = null
      this.propertySignature = ''
    },
    getPropertyEntities() {
      return this.propertyEntities
    },
    getProperties(parts) {
      // 1) 初始化属性操作状态
      this._propsInit(parts)
      // 2) 提取所有属性数据(type=0)
      this._getProperties({ parts, signature: this.propertySignature })
      // 3) 触发propertyState更新(watch钩子) => onGetProperties()
    },
    setProperties(parts, args) {
      // 初始化属性操作状态
      this._propsInit(parts)
      // 设置属性
      this._setProperties({
        parts,
        args,
        signature: this.propertySignature
      })
    },

    // 提示: 各组件应根据需要重新定义该函数
    // 根据vue mixin语法规则:组件的method会覆盖mixin的method
    onGetProperties(parts, props) {}
  }
}
